#ifndef SRC_HYPERCUBE_HYPERCUBE_HMM_MIDK
#define SRC_HYPERCUBE_HYPERCUBE_HMM_MIDK
#include "h_mat_mul.hpp"

hmm_constant_multipler *
build_hhmm_midk_constant_multipler(hmm_metric_collector *collector,
                                   const helib::EncryptedArray &ea,
                                   const cube_signature &eh_mnk);
void set_hhmm_midk_constant_multipler_clean_left(hmm_constant_multipler *cm);
void set_hhmm_midk_constant_multipler_clean_right(hmm_constant_multipler *cm);

void hhmm_midk(hmm_metric_collector *collector, hmm_constant_multipler *cm,
               const helib::EncryptedArray &ea, helib::Ctxt &AB,
               const helib::Ctxt &A, const helib::Ctxt &B);
void hhmm_midk_bsgs(hmm_metric_collector *collector, hmm_constant_multipler *cm,
                    const helib::EncryptedArray &ea, helib::Ctxt &AB,
                    const helib::Ctxt &A, const helib::Ctxt &B);

void hhmm_midk_mt(hmm_metric_collector *collector, hmm_constant_multipler *cm,
                  int threads, const helib::EncryptedArray &ea, helib::Ctxt &AB,
                  const helib::Ctxt &A, const helib::Ctxt &B);
void hhmm_midk_bsgs_mt(hmm_metric_collector *collector,
                       hmm_constant_multipler *cm, int threads,
                       const helib::EncryptedArray &ea, helib::Ctxt &AB,
                       const helib::Ctxt &A, const helib::Ctxt &B);

#endif /* SRC_HYPERCUBE_HYPERCUBE_HMM_MIDK */
